package com.le.tester.tip;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * createTime：2024/5/29 14:31
 * description：判断oss文件是否存在,把主题业务和参数初始化等分开是一个不错的选择
 */
public class OSSFileExistTester {

    //推荐使用创建线程池
    private static final ExecutorService pool = new ThreadPoolExecutor(3, 3,
            1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

    //public static final Lock lock = new ReentrantLock();


    private String endpointGZ = "https://oss-cn-guangzhou.aliyuncs.com";
    private String endpointSH = "https://oss-cn-shanghai.aliyuncs.com";
    private String accessKeyId = "LTAI5tDbQg5hC7tRAPDVrN6v";
    private String accessKeySecret = "NhgeBPVAY6AfbwbqyY29ybz5hfSwPw";

    private static final String URLPrefix = "https://";

    private static final String domainGZ = "oss-cn-guangzhou.aliyuncs.com";


    private OSS ossClientGZ = new OSSClientBuilder().build(endpointGZ, accessKeyId, accessKeySecret);
    //
    private OSS ossClientSH = new OSSClientBuilder().build(endpointSH, accessKeyId, accessKeySecret);

    private static final String dataURL = "E:\\Desktop\\picture_crw.json";

    public static void main(String[] args) {
//        new OSSFileExistTester().exec();
//        pool.shutdown();

        //使用CompletableFuture
        CompletableFuture.runAsync(new OssExistTask(), pool);
        //CompletableFuture.runAsync(new OSSDelTask(), pool);
        pool.shutdown();

    }

    //文件是否存在
    public List<String> fileExistJudge(List<OSSDto> fileInfo) {
        //System.out.println("当前次数:" + atomicInteger.incrementAndGet());
        List<String> result = new ArrayList<>();
        try {
            for (OSSDto item : fileInfo) {
                String oss_path = item.getOss_path();
                oss_path = oss_path.replaceAll(" ", "%20");
                String objectName = URLUtil.getPath(oss_path).replaceFirst("/", "");
                if (oss_path.contains("bojuematerial-prudcut-public") || oss_path.contains("bojuematerial-originalspare-private")) {
                    boolean b = ossClientGZ.doesObjectExist(item.getBucketName(), objectName);
                    if (!b) {
                        result.add("'" + oss_path + "'");
                    }
                } else {
                    boolean b = ossClientSH.doesObjectExist(item.getBucketName(), objectName);
                    if (!b) {
                        result.add("'" + oss_path + "'");
                    }
                }


            }
        } catch (Exception e) {
            return Collections.singletonList(e.toString());
        } finally {
            if (Objects.nonNull(ossClientGZ)) {
                ossClientGZ.shutdown();
            }
            if (Objects.nonNull(ossClientSH)) {
                ossClientSH.shutdown();
            }

        }
        return result;
    }

    /**
     * 批量删除oss文件，最多一次性删除1000
     *
     * @param bucketName:OssBucket中的name
     * @param objectNameList:文件完整路径列表。文件完整路径中不能包含Bucket名称。
     * @return List<String>:已经删除的文件路径
     */
    public List<String> batchDelFileOSS(String bucketName, List<String> objectNameList) {
        if (StringUtils.isBlank(bucketName) || CollectionUtils.isEmpty(objectNameList)) {
            return null;
        }
        List<String> resp = new ArrayList<>();
        try {
            DeleteObjectsResult deleteObjectsResult = ossClientGZ.deleteObjects(new DeleteObjectsRequest(bucketName)
                    .withKeys(objectNameList).withEncodingType("url"));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            for (String item : deletedObjects) {
                String ossPath = URLPrefix + bucketName + "." + domainGZ + "/" + item;
                resp.add("'" + ossPath + "'");
            }
            return resp;

        } catch (Exception e) {
            System.out.println("批量删除oss文件异常，e=" + e.getMessage());
            return resp;
        } finally {
            if (Objects.nonNull(ossClientGZ)) {
                ossClientGZ.shutdown();
            }
            if (Objects.nonNull(ossClientSH)) {
                ossClientSH.shutdown();
            }
        }

    }

    //文件是否存在
    static class OssExistTask implements Runnable {

        @Override
        public void run() {
            List<OSSDto> fileInfo = OSSFileExistTester.initOssPath();
            List<String> noExistFile = new OSSFileExistTester().fileExistJudge(fileInfo);

//            if (CollectionUtils.isEmpty(noExistFile)) {
//                System.out.println("全部存在");
//            }
            String join = StringUtils.join(noExistFile, "," + "\n");
            //System.out.println(join);

            System.out.println("此次不存在的数量：" + noExistFile.size());

            OSSFileExistTester.writeResult(join);
        }

    }


    //写出文件
    private static void writeResult(String str) {
        File file = new File("E:\\Desktop\\ossNoExist.txt");
        FileUtil.writeString(str, file, StandardCharsets.UTF_8);
    }

    //文件删除
    static class OSSDelTask implements Runnable {

        List<String> ppOssName = new ArrayList<>();
        List<String> osOssName = new ArrayList<>();
        List<String> alreadyDel = new ArrayList<>();

        @Override
        public void run() {
            List<OSSDto> fileList = OSSFileExistTester.initOssPath();
            for (OSSDto odItem : fileList) {
                String oss_path = odItem.getOss_path();
                String ossName = URLUtil.getPath(oss_path).replaceFirst("/", "");
                if (oss_path.contains("bojuematerial-originalspare-private")) {
                    osOssName.add(ossName);
                }
                if (oss_path.contains("bojuematerial-prudcut-public")) {
                    ppOssName.add(ossName);
                }
            }
            //do del
            if (!CollectionUtils.isEmpty(ppOssName)) {
                List<String> delFileOSSList = new OSSFileExistTester().batchDelFileOSS("bojuematerial-prudcut-public", ppOssName);
                alreadyDel.addAll(delFileOSSList);
            }

            if (!CollectionUtils.isEmpty(osOssName)) {
                List<String> delFileOSSList = new OSSFileExistTester().batchDelFileOSS("bojuematerial-originalspare-private", osOssName);
                alreadyDel.addAll(delFileOSSList);
            }
            String join = StringUtils.join(alreadyDel, "," + "\n");
            System.out.println("此次已删除的数量：" + alreadyDel.size());
            OSSFileExistTester.writeResult(join);
        }
    }

    public static List<OSSDto> getData() {
        File file = new File(dataURL);
        String content = FileUtil.readString(file, StandardCharsets.UTF_8);
        JSONObject record = JSONObject.parseObject(content);
        String ossPathStr = record.get("RECORDS").toString();

        return JSONArray.parseArray(ossPathStr, OSSDto.class);
    }

    //初始化ossPath
    public static List<OSSDto> initOssPath() {
        String bucketName = null;
        List<OSSDto> fileInfo = new ArrayList<>();
        List<OSSDto> ossPathList = OSSFileExistTester.getData();
        for (OSSDto odItem : ossPathList) {
            String oss_path = odItem.getOss_path();
            //System.out.println("oss path is " + oss_path);
            if (oss_path.contains("bojuematerial-originalspare-private")) {
                bucketName = "bojuematerial-originalspare-private";

            }
            if (oss_path.contains("bojuematerial-prudcut-public")) {
                bucketName = "bojuematerial-prudcut-public";
            }
            if (oss_path.contains("bojuematerial-phototruing-private")) {
                bucketName = "bojuematerial-phototruing-private";
            }

            if (oss_path.contains("bojuematerial-phototruing-private")) {
                bucketName = "bojuematerial-phototruing-private";
            }
            if (oss_path.contains("bojuematerial-phototruing-deepcold")) {
                bucketName = "bojuematerial-phototruing-deepcold";
            }

            OSSDto ossDto = new OSSDto();
            ossDto.setBucketName(bucketName);
            ossDto.setOss_path(oss_path);
            fileInfo.add(ossDto);
        }
        return fileInfo;
    }
}
